home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / recio202.zip / rfix.c < prev    next >
C/C++ Source or Header  |  1994-05-05  |  7KB  |  184 lines

  1. /****************************************************************************
  2.    MODULE: rfix.c
  3.   PURPOSE: recio functions used to fix bad data
  4. COPYRIGHT: (C) 1994 William Pierpoint
  5.  COMPILER: Borland C Version 3.1
  6.        OS: MSDOS Version 6.2
  7.   VERSION: 2.02
  8.   RELEASE: May 5, 1994
  9. *****************************************************************************
  10.  
  11. These functions make an educated guess at fixing bad data.  They are used in 
  12. the test programs.  They are not necessarily appropriate for your application.
  13.  
  14. Mnemonics are as follows:
  15.  
  16. Single letter (fix functions)
  17. -----------------------------
  18. b - base (prefix)
  19. c - character (suffix)
  20. d - double (suffix)
  21. f - float (suffix)
  22. i - integer (suffix)
  23. l - long (suffix)
  24. r - record pointer (first letter)
  25. u - unsigned (suffix)
  26.  
  27. Example: rbfixul() takes two arguments, record pointer and base (radix) of 
  28.          number, and fixes an unsigned long.
  29. *****************************************************************************/
  30.  
  31. #include <ctype.h>
  32. #include <float.h>
  33. #include <limits.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37.  
  38. #include "recio.h"
  39.  
  40. extern int str2c(const char *nptr, char **endptr);
  41. extern unsigned long str2ul(const char *nptr, char **endptr, int base);
  42.  
  43. /* clip value v between lower l and upper u bounds */
  44. #define range(l, v, u)  (min(max((l),(v)),(u)))
  45.  
  46. /****************************************************************************/
  47. static char *                 /* return pointer to string                   */
  48.     ctoa(                     /* convert char to string                     */
  49.         int   ch,             /* character to convert                       */
  50.         char *str)            /* string buffer to use                       */
  51. /****************************************************************************/
  52. {
  53.     if (ch > 0) str[0] = ch;
  54.     else str[0] = '\0';
  55.     str[1] = '\0';
  56.     return str;
  57. }
  58.  
  59. /****************************************************************************/
  60. static char *                /* return pointer to string                    */
  61.     tdtoa(                   /* convert floating point number to string     */
  62.         double d,            /* number to convert                           */
  63.         int    dig,          /* number of significant digits                */
  64.         char  *str)          /* string buffer to use                        */
  65. /****************************************************************************/
  66. {
  67.     char *sp=str;
  68.  
  69.     /* get one digit more than number of significant digits */
  70.     sprintf(str, "%.*E", dig, d);
  71.     
  72.     /* truncate last digit of significand */
  73.     while (*sp != 'E')  sp++;
  74.     memmove(sp-1, sp, strlen(sp)+1);
  75.     return str;
  76. }
  77.  
  78. /****************************************************************************/
  79. static int                   /* return 1 if neg zero, 0 otherwise           */
  80.     isnegzero(               /* does field buffer contain negative zero     */
  81.         REC *rp)             /* record pointer                              */
  82. /****************************************************************************/
  83. {
  84.      int negzero=0;          /* 0=not neg zero; 1=neg zero */
  85.      char *sp;               /* pointer to field buffer */
  86.      
  87.      sp = rflds(rp);
  88.      while (isspace(*sp)) sp++;
  89.      if (*sp++ != '-') goto done;
  90.      while (*sp == '0') sp++;
  91.      if (*sp < '0' || *sp > '9') negzero++;
  92. done:
  93.      return negzero;
  94.      
  95. }
  96.  
  97. /****************************************************************************/
  98. int rbfixi(REC *rp, int base) 
  99. /****************************************************************************/
  100. {
  101.     long l = range(INT_MIN, strtol(rflds(rp), NULL, base), INT_MAX);
  102.     if (isnegzero(rp)) return rsetfldstr(rp, "0");
  103.     return rsetfldstr(rp, ltoa(l, _r_nsbuf, base)); 
  104. }
  105.  
  106. /****************************************************************************/
  107. int rbfixui(REC *rp, int base)
  108. /****************************************************************************/
  109. {
  110.     unsigned long ul = min(str2ul(rflds(rp), NULL, base), UINT_MAX);
  111.     return rsetfldstr(rp, ultoa(ul, _r_nsbuf, base));
  112. }
  113.  
  114. /****************************************************************************/
  115. int rbfixl(REC *rp, int base)
  116. /****************************************************************************/
  117. {
  118.     long l = range(LONG_MIN, strtol(rflds(rp), NULL, base), LONG_MAX);
  119.     if (isnegzero(rp)) return rsetfldstr(rp, "0");
  120.     return rsetfldstr(rp, ltoa(l, _r_nsbuf, base));
  121. }
  122.  
  123. /****************************************************************************/
  124. int rbfixul(REC *rp, int base) 
  125. /****************************************************************************/
  126. {
  127.     unsigned long ul= min(str2ul(rflds(rp), NULL, base), ULONG_MAX);
  128.     return rsetfldstr(rp, ultoa(ul, _r_nsbuf, base));
  129. }
  130.  
  131. /****************************************************************************/
  132. int rfixi(REC *rp) 
  133. /****************************************************************************/
  134.      return rbfixi(rp, 10); 
  135. }
  136.  
  137. /****************************************************************************/
  138. int rfixui(REC *rp)
  139. /****************************************************************************/
  140. {  
  141.     return rbfixui(rp, 10);
  142. }
  143.  
  144. /****************************************************************************/
  145. int rfixl(REC *rp)
  146. /****************************************************************************/
  147. {
  148.     return rbfixl(rp, 10);
  149. }
  150.  
  151. /****************************************************************************/
  152. int rfixul(REC *rp)
  153. /****************************************************************************/
  154. {
  155.     return rbfixul(rp, 10);
  156. }
  157.  
  158. /****************************************************************************/
  159. int rfixf(REC *rp) 
  160. /****************************************************************************/
  161. {
  162.     double d = range(-FLT_MAX, strtod(rflds(rp), NULL), FLT_MAX);
  163.     if (d > -FLT_MIN && d < FLT_MIN) d=0.0;
  164.     return rsetfldstr(rp, tdtoa((float) d, FLT_DIG, _r_nsbuf));
  165. }
  166.  
  167. /****************************************************************************/
  168. int rfixd(REC *rp)
  169. /****************************************************************************/
  170. {
  171.     double d = strtod(rflds(rp), NULL);
  172.     if (d > -DBL_MIN && d < DBL_MIN) d=0.0;
  173.     return rsetfldstr(rp, tdtoa(d, DBL_DIG, _r_nsbuf));
  174. }
  175.  
  176. /****************************************************************************/
  177. int rfixc(REC *rp) 
  178. /****************************************************************************/
  179. {
  180.     int ch = str2c(rflds(rp), NULL);
  181.     return rsetfldstr(rp, ctoa(ch, _r_nsbuf));
  182. }
  183.